home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / utilit~1 / gdb35src.zoo / dist-gdb / dep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-12  |  21.6 KB  |  822 lines

  1. /* Machine-dependent code which would otherwise be in inflow.c and core.c,
  2.    for GDB, the GNU debugger.
  3.    Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
  4.  
  5. This file is part of GDB.
  6.  
  7. GDB is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GDB is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GDB; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* This one is a try to use the MiNT PROCFS for debugging. I simply re-hacked
  22.     all calls to ptrace into calls to Fopen/Fclose/Fcntl. I really hope this
  23.     works, but it's a bit messy. At best, *VERY* little error checking is done.
  24.     I should really do this some time...
  25.  
  26.     Suggestions, comments and bugfixes welcome. Send mail to
  27.  
  28.     Joerg.Hessdoerfer@EUROPA.rs.kp.dlr.de (preferred 'till May '93)
  29.     Hessdorf@sun.ph-cip.uni-koeln.de
  30.  
  31. */
  32.     
  33. #include <stdio.h>
  34. #include "defs.h"
  35. #include "param.h"
  36. #include "frame.h"
  37. #include "inferior.h"
  38.  
  39. #include <sys/param.h>
  40. #include <sys/dir.h>
  41. #include <signal.h>
  42. #include <sys/ioctl.h>
  43. #include <fcntl.h>
  44.  
  45. #include <mintbind.h>
  46. #include <uproc.h> /* uproc.h from mint-distrib. Doesn't need ufile.h */
  47. #define PCTXTSIZE    (('P'<< 8) | 3)
  48. #define PSETFLAGS    (('P'<< 8) | 4)
  49. #define PGETFLAGS    (('P'<< 8) | 5)
  50. #define PTRACESFLAGS    (('P'<< 8) | 6)
  51. #define PTRACEGFLAGS    (('P'<< 8) | 7)
  52. #    define    P_ENABLE    (1 << 0)    /* enable tracing */
  53.  
  54. #define PTRACEGO    (('P'<< 8) | 8)
  55. #define PTRACEFLOW    (('P'<< 8) | 9)
  56. #define PTRACESTEP    (('P'<< 8) | 10)
  57. #define PTRACE11    (('P'<< 8) | 11)    /* unused, reserved */
  58.  
  59. #define SHMGETBLK    (('M'<< 8) | 0)
  60. #define SHMSETBLK    (('M'<< 8) | 1)
  61.  
  62. #include <st-out.h>
  63. #include <sys/file.h>
  64. #include <sys/stat.h>
  65.  
  66. #include <symtab.h> /* needed for relocator */
  67.  
  68. extern char registers[];
  69.  
  70. extern int errno;
  71. extern int attach_flag;
  72.  
  73.  
  74. int inferior_handle;
  75. char inferior_name[64];    
  76.  
  77. /* This function simply calls ptrace with the given arguments.  
  78.    It exists so that all calls to ptrace are isolated in this 
  79.    machine-dependent file. */
  80. /* That's what it had done - now it calls Fcntl with the same ideas,
  81.     but only some ptrace modes are supported (well, only the ones used
  82.     from outside in gdb). */
  83. int
  84. call_ptrace (request, pid, arg3, arg4)
  85.      int request, pid, arg3, arg4;
  86. {
  87.     char name[64];
  88.     int handle;
  89.     
  90.     switch(request)
  91.     {
  92.         case 0:
  93.             sprintf(name,"U:\\PROC\\.%03d",Pgetpid());
  94.             handle=Fopen(name,2);
  95.             Fcntl(handle,P_ENABLE,PTRACESFLAGS);
  96.             Fclose(handle);
  97.             break;
  98.  
  99.         default:
  100.             printf("_call_ptrace() called with unimplemented request: %d\n",request);
  101.     }
  102.             
  103. }
  104.  
  105. kill_inferior ()
  106. {
  107.     short msig;
  108.     
  109.   if (remote_debugging)
  110.     return;
  111.   if (inferior_pid == 0)
  112.     return;
  113.  
  114.    msig=SIGKILL; /* signal can't be ignored! */
  115.     Fcntl(inferior_handle,&msig,PTRACEGO); /* set the child in motion... */
  116.     Fclose(inferior_handle);
  117.     
  118.   wait (0);
  119.   inferior_died ();
  120. }
  121.  
  122. /* This is used when GDB is exiting.  It gives less chance of error.*/
  123.  
  124. kill_inferior_fast ()
  125. {
  126.     short msig;
  127.     
  128.   if (remote_debugging)
  129.     return;
  130.   if (inferior_pid == 0)
  131.     return;
  132.  
  133.    msig=SIGKILL; /* signal can't be ignored! */
  134.     Fcntl(inferior_handle,&msig,PTRACEGO); /* set the child in motion... */
  135.     Fclose(inferior_handle);
  136.     
  137.   wait (0);
  138. }
  139.  
  140. /* Resume execution of the inferior process.
  141.    If STEP is nonzero, single-step it.
  142.    If SIGNAL is nonzero, give it that signal.  */
  143.  
  144. void
  145. resume (step, signal)
  146.      int step;
  147.      int signal;
  148. {
  149.   errno = 0;
  150.   if (remote_debugging)
  151.     remote_resume (step, signal);
  152.   else
  153.     {
  154.         short msig;
  155.         msig=signal;
  156.         errno=Fcntl(inferior_handle,&msig,step ? PTRACESTEP : PTRACEGO);
  157.       if (errno)
  158.     perror_with_name ("ptrace");
  159.     }
  160. }
  161.  
  162. #ifdef ATTACH_DETACH
  163.  
  164. /* Start debugging the process whose number is PID.  */
  165.  
  166. attach (pid)
  167.      int pid;
  168. {
  169.   errno = 0;
  170.     sprintf(inferior_name,"U:\\PROC\\.%03d",pid);
  171.     inferior_handle=Fopen(inferior_name,2);
  172.     if(inferior_handle>0)errno=Fcntl(inferior_handle,P_ENABLE,PTRACESFLAGS);
  173.     else errno=inferior_handle;
  174.  
  175.   if (errno)
  176.     perror_with_name ("ptrace");
  177.   attach_flag = 1;
  178.   return pid;
  179. }
  180.  
  181. /* Stop debugging the process whose number is PID
  182.    and continue it with signal number SIGNAL.
  183.    SIGNAL = 0 means just continue it.  */
  184.  
  185. void
  186. detach (signal)
  187.      int signal;
  188. {
  189.   errno = 0;
  190.  
  191.     errno=Fcntl(inferior_handle,0,PTRACESFLAGS);
  192.     Fclose(inferior_handle);
  193.  
  194.   if (errno)
  195.     perror_with_name ("ptrace");
  196.   attach_flag = 0;
  197. }
  198. #endif /* ATTACH_DETACH */
  199.  
  200. void
  201. fetch_inferior_registers ()
  202. {
  203.     long curprocaddr;
  204.     long ctxtsize;
  205.     CONTEXT c;
  206.  
  207.   if (remote_debugging)
  208.     remote_fetch_registers (registers);
  209.   else
  210.     {
  211.         Fcntl(inferior_handle,&curprocaddr,PPROCADDR);        /* get start of process' base page */
  212.         Fcntl(inferior_handle,&ctxtsize,PCTXTSIZE);              /* get length of process' context */
  213.         curprocaddr-=2*ctxtsize;                                      /* get start of process' first context */
  214.         Fseek(curprocaddr,inferior_handle,0);                      /* advance to this address */
  215.         Fread(inferior_handle,(long)sizeof(CONTEXT),&c);    /* and read the context */
  216.  
  217.       bcopy (&c.regs, registers, 16 * 4);
  218. #ifdef FP0_REGNUM
  219.       bcopy (&c.fregs, ®isters[REGISTER_BYTE (FP0_REGNUM)],3*4*8);
  220. #endif 
  221.       *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = (int)((unsigned short)c.sr);
  222.       *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = c.pc;
  223. #ifdef FP0_REGNUM
  224.       bcopy (&c.fstate, ®isters[REGISTER_BYTE (FPC_REGNUM)],216);
  225.       bcopy (&c.fctrl, ®isters[REGISTER_BYTE (FPC_REGNUM)]+216,3*4);
  226. #endif
  227.     }
  228. }
  229.  
  230. /* Store our register values back into the inferior.
  231.    If REGNO is -1, do this for all registers.
  232.    Otherwise, REGNO specifies which register (so we can save time).  */
  233.  
  234. store_inferior_registers (regno)
  235.      int regno;
  236. {
  237.     long curprocaddr;
  238.     long ctxtsize;
  239.     CONTEXT c;
  240.  
  241.   if (remote_debugging)
  242.     remote_store_registers (registers);
  243.   else
  244.     {
  245.       bcopy (registers, &c.regs, 16 * 4);
  246. #ifdef FP0_REGNUM
  247.       bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], &c.fregs,8*3*4);
  248. #endif
  249.       c.sr = *(int *)®isters[REGISTER_BYTE (PS_REGNUM)];
  250.       c.pc = *(int *)®isters[REGISTER_BYTE (PC_REGNUM)];
  251.  
  252. #ifdef FP0_REGNUM
  253.       bcopy (®isters[REGISTER_BYTE (FPC_REGNUM)],&c.fstate,216);
  254.       bcopy (®isters[REGISTER_BYTE (FPC_REGNUM)]+216,&c.fctrl,3*4);
  255. #endif
  256.  
  257.         Fcntl(inferior_handle,&curprocaddr,PPROCADDR);        /* get start of process' base page */
  258.         Fcntl(inferior_handle,&ctxtsize,PCTXTSIZE);              /* get length of process' context */
  259.         curprocaddr-=2*ctxtsize;                                      /* get start of process' first context */
  260.         Fseek(curprocaddr,inferior_handle,0);                      /* advance to this address */
  261.         Fwrite(inferior_handle,(long)sizeof(CONTEXT),&c);    /* and write the context */
  262.  
  263.     }
  264. }
  265.  
  266.  
  267. /* Copy LEN bytes from inferior's memory starting at MEMADDR
  268.    to debugger memory starting at MYADDR. 
  269.    On failure (cannot read from inferior, usually because address is out
  270.    of bounds) returns the value of errno. */
  271.  
  272. int
  273. read_inferior_memory (memaddr, myaddr, len)
  274.      CORE_ADDR memaddr;
  275.      char *myaddr;
  276.      int len;
  277. {
  278.   register int i;
  279.   /* Round starting address down to longword boundary.  */
  280.   register CORE_ADDR addr = memaddr & - sizeof (int);
  281.   /* Round ending address up; get number of longwords that makes.  */
  282.   register int count
  283.     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  284.   /* Allocate buffer of that many longwords.  */
  285.   register int *buffer = (int *) alloca (count * sizeof (int));
  286.   extern int errno;
  287.  
  288.     if(remote_debugging)
  289.     {
  290.   /* Read all the longwords */
  291.       for (i = 0; i < count; i++, addr += sizeof (int))
  292.         {
  293.           errno = 0;
  294.         buffer[i] = remote_fetch_word (addr);
  295.           if (errno)
  296.         return errno;
  297.         }
  298.     
  299.       /* Copy appropriate bytes out of the buffer.  */
  300.       bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
  301.     }
  302.     else
  303.     {
  304.         Fseek(memaddr,inferior_handle,0);
  305.         errno=Fread(inferior_handle,len,myaddr);
  306.         if(errno<0){ errno=-(errno); return errno; }
  307.         else errno=0;
  308.     }
  309.   return 0;
  310. }
  311.  
  312. /* Copy LEN bytes of data from debugger memory at MYADDR
  313.    to inferior's memory at MEMADDR.
  314.    On failure (cannot write the inferior)
  315.    returns the value of errno.  */
  316.  
  317. int
  318. write_inferior_memory (memaddr, myaddr, len)
  319.      CORE_ADDR memaddr;
  320.      char *myaddr;
  321.      int len;
  322. {
  323.   register int i;
  324.   /* Round starting address down to longword boundary.  */
  325.   register CORE_ADDR addr = memaddr & - sizeof (int);
  326.   /* Round ending address up; get number of longwords that makes.  */
  327.   register int count
  328.     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  329.   /* Allocate buffer of that many longwords.  */
  330.   register int *buffer = (int *) alloca (count * sizeof (int));
  331.   extern int errno;
  332.  
  333.   /* Fill start and end extra bytes of buffer with existing memory data.  */
  334.  
  335.   if (remote_debugging)
  336.   {
  337.     buffer[0] = remote_fetch_word (addr);
  338.  
  339.       if (count > 1)
  340.         buffer[count - 1]
  341.           = remote_fetch_word (addr + (count - 1) * sizeof (int));
  342.     
  343.       /* Copy data to be written over corresponding part of buffer */
  344.     
  345.       bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
  346.     
  347.       /* Write the entire buffer.  */
  348.     
  349.       for (i = 0; i < count; i++, addr += sizeof (int))
  350.         {
  351.           errno = 0;
  352.         remote_store_word (addr, buffer[i]);
  353.           if (errno)
  354.         return errno;
  355.         }
  356.   }
  357.   else
  358.     {
  359.         Fseek(memaddr,inferior_handle,0);
  360.         errno=Fwrite(inferior_handle,len,myaddr);
  361.         if(errno<0){ errno=-(errno); return errno; }
  362.         else errno=0;
  363.     }
  364.   return 0;
  365. }
  366.  
  367. long inferior_gettxtstrt(void)
  368. {
  369.         long curprocaddr;
  370.  
  371.         if(inferior_pid)
  372.         {
  373.             Fcntl(inferior_handle,&curprocaddr,PBASEADDR);
  374.             curprocaddr+=256;
  375.             return curprocaddr;
  376.         }
  377.         else return NULL;
  378. }
  379.  
  380.  
  381. /* Machine-dependent code which would otherwise be in core.c */
  382. /* Work with core dump and executable files, for GDB. */
  383.  
  384. #ifndef N_TXTADDR
  385. #define N_TXTADDR(hdr) 0
  386. #endif /* no N_TXTADDR */
  387.  
  388. #ifndef N_DATADDR
  389. #define N_DATADDR(hdr) hdr.a_text
  390. #endif /* no N_DATADDR */
  391.  
  392. /* Non-zero if this is an object (.o) file, rather than an executable.
  393.    Distinguishing between the two is rarely necessary (and seems like
  394.    a hack, but there is no other way to get the text and data
  395.    addresses--N_TXTADDR should probably take care of
  396.    this, but it doesn't).  */
  397. /* This definition will not work
  398.    if someone decides to make ld preserve relocation info.  */
  399. #define IS_OBJECT_FILE(hdr) (hdr.a_trsize != 0)
  400.   
  401. /* Make COFF and non-COFF names for things a little more compatible
  402.    to reduce conditionals later.  */
  403.  
  404. #ifdef COFF_FORMAT
  405. #define a_magic magic
  406. #endif
  407.  
  408. #ifndef COFF_FORMAT
  409. #ifndef AOUTHDR
  410. #define AOUTHDR struct aexec
  411. #endif
  412. #endif
  413.  
  414. extern char *sys_siglist[];
  415.  
  416. /* Hook for `exec_file_command' command to call.  */
  417.  
  418. extern void (*exec_file_display_hook) ();
  419.    
  420. /* File names of core file and executable file.  */
  421.  
  422. extern char *corefile;
  423. extern char *execfile;
  424.  
  425. /* Descriptors on which core file and executable file are open.
  426.    Note that the execchan is closed when an inferior is created
  427.    and reopened if the inferior dies or is killed.  */
  428.  
  429. extern int corechan;
  430. extern int execchan;
  431.  
  432. /* Last modification time of executable file.
  433.    Also used in source.c to compare against mtime of a source file.  */
  434.  
  435. extern int exec_mtime;
  436.  
  437. /* Virtual addresses of bounds of the two areas of memory in the core file.  */
  438.  
  439. extern CORE_ADDR data_start;
  440. extern CORE_ADDR data_end;
  441. extern CORE_ADDR stack_start;
  442. extern CORE_ADDR stack_end;
  443.  
  444. /* Virtual addresses of bounds of two areas of memory in the exec file.
  445.    Note that the data area in the exec file is used only when there is no core file.  */
  446.  
  447. extern CORE_ADDR text_start;
  448. extern CORE_ADDR text_end;
  449.  
  450. extern CORE_ADDR exec_data_start;
  451. extern CORE_ADDR exec_data_end;
  452.  
  453. /* Address in executable file of start of text area data.  */
  454.  
  455. extern int text_offset;
  456.  
  457. /* Address in executable file of start of data area data.  */
  458.  
  459. extern int exec_data_offset;
  460.  
  461. /* Address in core file of start of data area data.  */
  462.  
  463. extern int data_offset;
  464.  
  465. /* Address in core file of start of stack area data.  */
  466.  
  467. extern int stack_offset;
  468.   
  469. #ifdef COFF_FORMAT
  470. /* various coff data structures */
  471.  
  472. extern FILHDR file_hdr;
  473. extern SCNHDR text_hdr;
  474. extern SCNHDR data_hdr;
  475.  
  476. #endif /* not COFF_FORMAT */
  477.  
  478. /* a.out header saved in core file.  */
  479.   
  480. extern AOUTHDR core_aouthdr;
  481.  
  482. /* a.out header of exec file.  */
  483.  
  484. extern AOUTHDR exec_aouthdr;
  485.  
  486. extern void validate_files ();
  487.  
  488. core_file_command (filename, from_tty) /* on a ST, we don't have cor dumps - so don't use that */
  489.      char *filename;
  490.      int from_tty;
  491. {
  492. }
  493.  
  494. exec_file_command (filename, from_tty)
  495.      char *filename;
  496.      int from_tty;
  497. {
  498.   int val;
  499.  
  500.   /* Eliminate all traces of old exec file.
  501.      Mark text segment as empty.  */
  502.  
  503.   if (execfile)
  504.     free (execfile);
  505.   execfile = 0;
  506.   data_start = 0;
  507.   data_end -= exec_data_start;
  508.   text_start = 0;
  509.   text_end = 0;
  510.   exec_data_start = 0;
  511.   exec_data_end = 0;
  512.   if (execchan >= 0)
  513.     close (execchan);
  514.   execchan = -1;
  515.  
  516.   /* Now open and digest the file the user requested, if any.  */
  517.  
  518.   if (filename)
  519.     {
  520.       filename = tilde_expand (filename);
  521.       make_cleanup (free, filename);
  522.       
  523.       execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
  524.             &execfile);
  525.       if (execchan < 0)
  526.     perror_with_name (filename);
  527.       {
  528.     struct stat st_exec;
  529.     val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
  530.  
  531.     if (val < 0)
  532.       perror_with_name (filename);
  533.  
  534.    text_start = A_TXTOFF (exec_aouthdr);
  535.    exec_data_start = A_DATOFF (exec_aouthdr);
  536.  
  537.     text_offset = A_TXTOFF (exec_aouthdr);
  538.     exec_data_offset = A_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
  539.  
  540.     text_end = text_start + exec_aouthdr.a_text;
  541.         exec_data_end = exec_data_start + exec_aouthdr.a_data;
  542.     data_start = exec_data_start;
  543.     data_end += exec_data_start;
  544.       }
  545.       validate_files ();
  546.     }
  547.   else if (from_tty)
  548.     printf ("No exec file now.\n");
  549.  
  550.   /* Tell display code (if any) about the changed file name.  */
  551.   if (exec_file_display_hook)
  552.     (*exec_file_display_hook) (filename);
  553. }
  554.  
  555.  
  556. /*** JOE: this was taken from JRD's port of GDB 2.6!
  557.           Thanx, pal! That *REALLY* helped!         ***/
  558.           
  559. /********************************************************************
  560.   
  561.   This next thing is the symbol-table relocator.  We use it after 
  562.   starting a child program.
  563.   
  564.   Walk thru all symbol tables looking for syms in VAR_NAMESPACE.
  565.   When find one, if its address_class is LOC_STATIC, relocate its
  566.   value by base_address.  Then cross fingers and pray...
  567.   
  568.   */
  569. relocate_apropriate_symbols(base_address)
  570. long base_address;
  571. {
  572.     struct symtab * s;
  573.     struct symbol * sym;
  574.     struct blockvector * bv, *last_bv = 0;
  575.     struct block * block;
  576.     struct linetable * l;
  577.     int nsyms, symnum, i;
  578.     extern char *version;
  579.  
  580. #ifdef DEBUG
  581.     if(atari_debug)
  582.     {
  583.       fprintf_filtered(stderr,"Reloc constant %ld %X\n", base_address, base_address);
  584.     }
  585. #endif
  586.     for (s = symtab_list ; s ; s = s->next)
  587.     {
  588.     l = LINETABLE(s);
  589. #ifdef DEBUG
  590.     if(atari_debug)
  591.     {
  592.       fprintf_filtered(stderr,
  593.           "reloc syms table %X file '%s' linetable %08X(%ld) %d items\n",
  594.         s, s->filename, l,l, l->nitems);
  595.         }
  596. #endif
  597.         { 
  598.         int n = l->nitems;
  599.         struct linetable_entry *item;
  600.         
  601. #ifdef DEBUG
  602.         if(atari_debug && (n <= 0))
  603.         {
  604.         fprintf_filtered(stderr,"*********linetable with %d items\n", n);
  605.         }
  606. #endif        
  607.         for (i = 0 ; i < n ; i++)
  608.         {
  609.         item = &(l->item[i]);
  610. #ifdef DEBUG
  611.         if(atari_debug)
  612.         {
  613.           fprintf_filtered(stderr, "    %d: line %d %X(%ld)->%X(%ld)\n",
  614.             i, item->line, item->pc, item->pc,
  615.             item->pc+base_address, item->pc+base_address);
  616.             }
  617. #endif
  618.         item->pc += base_address;
  619.         }
  620.     }
  621.     bv = BLOCKVECTOR (s);
  622.     if (bv == last_bv)
  623.     {
  624.         /* already relocated */
  625. #ifdef DEBUG
  626.         if(atari_debug)
  627.         {
  628.           fprintf_filtered(stderr,"Skipping block vector %X(%d) already relocated\n", bv,bv); 
  629.         }
  630. #endif
  631.         continue;
  632.     }
  633.     last_bv = bv;
  634.     for (i = 0 ; i < BLOCKVECTOR_NBLOCKS(bv) ; i++)
  635.     {
  636.         block = BLOCKVECTOR_BLOCK (bv, i);
  637. #ifdef DEBUG
  638.         if(atari_debug)
  639.         {
  640.           fprintf_filtered(stderr, " block %d: in %X(%d)\n", i, bv, bv);
  641.         }
  642. #endif
  643.         relocate_apropriate_block_symbols(block, base_address);
  644.     }
  645.     }
  646. #ifdef DEBUG
  647.     if(atari_debug)
  648.     {
  649.       fprintf_filtered(stderr,"Relocatings %d misc functions\n", misc_function_count);
  650.     }
  651. #endif
  652.     /* relocate the misc functions */
  653.     for (i = 0; i < misc_function_count; i++)
  654.     {
  655. #ifdef DEBUG
  656.     if(atari_debug > 1)
  657.     {
  658.       fprintf_filtered(stderr, "%s: %X(%ld)->%X(%ld)\n", misc_function_vector[i].name,
  659.             misc_function_vector[i].address, misc_function_vector[i].address,
  660.         misc_function_vector[i].address+base_address, misc_function_vector[i].address+base_address);
  661.         }
  662. #endif    
  663.     misc_function_vector[i].address += base_address;
  664.     }
  665.     
  666. }
  667.  
  668. relocate_apropriate_block_symbols(block, base_address)
  669. struct block * block;
  670. long base_address;
  671. {
  672.     struct symbol * sym;
  673.     int nsyms, symnum;
  674.     
  675.     /*    for ( ; block ; block = BLOCK_SUPERBLOCK(block)) */
  676.     {
  677.     BLOCK_START(block) += base_address;
  678.     BLOCK_END(block) += base_address;
  679.     nsyms = BLOCK_NSYMS (block);
  680. #ifdef DEBUG
  681.     if(atari_debug)
  682.     {
  683.       fprintf_filtered(stderr, " %d syms block %X(%ld)\n", nsyms, block, block);
  684.         }
  685. #endif
  686.     for (symnum = 0 ; symnum < nsyms ; symnum++)
  687.     {
  688.         sym = BLOCK_SYM (block, symnum);
  689. #ifdef DEBUG
  690.         if(atari_debug)
  691.         {
  692.           fprintf_filtered(stderr, "  sym %d %X name '%s'",
  693.               symnum, sym, SYMBOL_NAME(sym));
  694.         }
  695. #endif
  696.         if ((sym->namespace == VAR_NAMESPACE) &&
  697.         ((sym->class == LOC_STATIC) || (sym->class == LOC_LABEL)))
  698.         {
  699. #ifdef DEBUG
  700.         if(atari_debug)
  701.         {
  702.         fprintf_filtered(stderr, " is relocatable: (%s, %s) %X->%X  %ld->%ld\n",
  703.             d_namespace[sym->namespace], d_aclass[sym->class],
  704.             sym->value.value, sym->value.value + base_address,
  705.             sym->value.value, sym->value.value + base_address);
  706.             }
  707. #endif
  708.         sym->value.value += base_address;
  709.         }
  710.         else if (sym->class == LOC_BLOCK)
  711.         {
  712. #ifdef DEBUG
  713.         if(atari_debug)
  714.         {
  715.         fprintf_filtered(stderr, " is a LOC_block(%s %s)... %X\n",
  716.         d_namespace[sym->namespace], d_aclass[sym->class], sym->value.block);
  717.             }
  718. #endif
  719. #if 0
  720.         relocate_apropriate_block_symbols(sym->value.block, base_address);
  721. #else
  722.             {
  723.             struct block * bl = sym->value.block;
  724. #ifdef DEBUG0
  725.             if(atari_debug)
  726.             {
  727.             fprintf_filtered(stderr, "  start %X->%X\n", 
  728.                 BLOCK_START(bl), BLOCK_START(bl) + base_address);
  729.             }
  730. #endif
  731.             /* BLOCK_START(bl) += base_address; */
  732. #ifdef DEBUG0
  733.             if(atari_debug)
  734.             {
  735.             fprintf_filtered(stderr, "  end   %X->%X\n", 
  736.                 BLOCK_END(bl), BLOCK_END(bl) + base_address);
  737.             }
  738. #endif
  739.             /* BLOCK_END(bl) += base_address; */
  740.             }
  741. #endif
  742. #ifdef DEBUG
  743.         if(atari_debug)
  744.         {
  745.           fprintf_filtered(stderr, " ...end block\n");
  746.             }
  747. #endif
  748.         }
  749.         else
  750.         {
  751. #ifdef DEBUG
  752.         if(atari_debug)
  753.         {
  754.           fprintf_filtered(stderr, " is not relocatable: (%s, %s)\n",
  755.             d_namespace[sym->namespace], d_aclass[sym->class]);
  756.             }
  757. #endif
  758.         }
  759.     }
  760.     }
  761. }
  762.  
  763. /* This one's by JOE. It relocates breakpoints at 'run_command' time,
  764.    so it's possible to specify breakpoints *BEFORE* actually running
  765.    the inferior. Thus no stop immediate after the start of the
  766.    inferior is needed. Nice, huh?!? - We come close to the behaviour
  767.    of the UN*X GDB!! */
  768.  
  769. static char break_insn[] = BREAKPOINT;
  770.  
  771. enum enable { disabled, enabled, temporary, delete};
  772.  
  773. struct breakpoint
  774. {
  775.   struct breakpoint *next;
  776.   /* Number assigned to distinguish breakpoints.  */
  777.   int number;
  778.   /* Address to break at.  */
  779.   CORE_ADDR address;
  780.   /* Line number of this address.  Redundant.  */
  781.   int line_number;
  782.   /* Symtab of file of this address.  Redundant.  */
  783.   struct symtab *symtab;
  784.   /* Zero means disabled; remember the info but don't break here.  */
  785.   enum enable enable;
  786.   /* Non-zero means a silent breakpoint (don't print frame info
  787.      if we stop here). */
  788.   unsigned char silent;
  789.   /* Number of stops at this breakpoint that should
  790.      be continued automatically before really stopping.  */
  791.   int ignore_count;
  792.   /* "Real" contents of byte where breakpoint has been inserted.
  793.      Valid only when breakpoints are in the program.  */
  794.   char shadow_contents[sizeof break_insn];
  795.   /* Nonzero if this breakpoint is now inserted.  */
  796.   char inserted;
  797.   /* Nonzero if this is not the first breakpoint in the list
  798.      for the given address.  */
  799.   char duplicate;
  800.   /* Chain of command lines to execute when this breakpoint is hit.  */
  801.   struct command_line *commands;
  802.   /* Stack depth (address of frame).  If nonzero, break only if fp
  803.      equals this.  */
  804.   FRAME_ADDR frame;
  805.   /* Conditional.  Break only if this expression's value is nonzero.  */
  806.   struct expression *cond;
  807. };
  808.  
  809. #define ALL_BREAKPOINTS(b)  for (b = breakpoint_chain; b; b = b->next)
  810.  
  811. /* Chain of all breakpoints defined.  */
  812.  
  813. extern struct breakpoint *breakpoint_chain;
  814.    
  815. void relocate_breakpoints(long address)
  816. {
  817.     struct breakpoint *b;
  818.     
  819.       ALL_BREAKPOINTS(b) b->address+=address;
  820. }
  821.  
  822.